#include <stdio.h>
#include <string.h>
#include <ctype.h>

//	выводит дамп в хекс виде
//	compile : cc -Wall -std=c99 printhex.c

#define HEXLINEWIDTH	16
#define getChar(x) (isprint((x)) && (x) != ' ') ? x : '.'

void printHexDump(FILE * f, void * data, size_t dataLen)
{
	int lineCnt = 0;	//	текущий индекс в строке
	unsigned char * hexData = data;
	
	for(int currentIdx = 0; currentIdx < dataLen; ++currentIdx)
	{		
		//	выводим адрес начала строки
		if(!lineCnt)
			fprintf(f, "0x%08x:\t", currentIdx);
		
		++lineCnt;
		
		//	выводим символ
		fprintf(f, "%02x ", hexData[currentIdx]);
		
		//	line break
		int isLastIdx = (currentIdx == dataLen - 1);
		if(lineCnt == HEXLINEWIDTH || isLastIdx)
		{ 			
			//	выравниваем если нужно
			int padCtn = HEXLINEWIDTH - lineCnt;
			while(padCtn--) fprintf(f, "   ");
			
			//	оступ между двумя колонками
			fprintf(f, "\t");
			
			//	печатаем ascii символы
			for(int lineIdx = currentIdx - lineCnt; lineIdx < currentIdx; ++lineIdx)
				fprintf(f, "%c", getChar(hexData[lineIdx]));
				
			//	переходим к следующей строке
			fprintf(f, "\n");			
			lineCnt = 0;
		}			
	}
}

int main(void)
{
	//	пример использования
	char * buffer = "test buffer for hex dump\x02\x89\n";
	printHexDump(stdout, buffer, strlen(buffer));
	printHexDump(stdout, main, 0x100);
	
	return 0;
}